<?php
/**
 * 
 * Список 
 * 
 * @author Chashin Evgeniy
 * @version 0.2.1
 * 
 */
class Zen_List extends Zen_Model{
	
	/**
	 * Таблица
	 * @var Zend_Db_Table object
	 */
	protected $table = false;
	
	public function setOptions(array $options) {
		$methods = get_class_methods ( $this );
		foreach ( $options as $key => $value ) {
			$method = 'set' . ucfirst ( $key );
			if (in_array ( $method, $methods )) {
				$this->$method ( $value );
			}
		}
		return $this;
	}
	
	/**
	 * @param Zend_Db_Table $table
	 */
	public function setTable($table) {
		if ($table instanceof Zend_Db_Table_Abstract) {
			$this->table = $table;
		} else {
			if (is_string ( $table )) {
				$this->table = new Zend_Db_Table ( $table );
			}
		}
		return $this;
	}
	
	public function __construct($table = false) {
		if ($table) {
			$this->setTable ( $table );
		} else {
			throw new Zend_Exception ( 'Invalid table for class Zen_List' );
		}
	}
	
	//CRUD
	/**
	 * Создание одной записи в таблице
	 * @param array $params
	 * @return int|boolean
	 */
	public function create($params) {
		//Вызов события beforeCreate
		$params = $this->beforeCreate ( $params );
		if ($params) {
			$id = $this->table->createRow ( $params )->save ();
			if ($id) {
				$this->afterCreate ( $id, $params );
				$this->afterChange ();
				$this->globalChange ();
			}
			return $id;
		}else {
			return false;
		}
	}
	/**
	 * Чтение одной записи из таблицы
	 * @param string $where
	 * @return int|boolean
	 */
	public function read($where) {
		$res = $this->getTable ()->select ()->where ( $where )->limit ( 1 )->query ()->fetch ();
		$res=$this->afterRead($res);
		return $res;
	}
	/**
	 * Обновление параметров одной записи в таблице
	 * @param int $id
	 * @param array $params ассоциативный массив с параметрами записи
	 * @return boolean
	 */
	public function update($id, $params) {
		$id = preg_replace ( '/\D/', '', $id );
		if ($id > 0) {
			//Вызов события beforeUpdate
			$params = $this->beforeUpdate ( $id, $params );
			$row = $this->table->find ( $id )->current ();
			if ($row) {
				$res = $row->setFromArray ( $params )->save ();
				if ($res) {
					$this->afterUpdate ( $id, $params );
					$this->afterChange ();
					$this->globalChange ();
				}
			} else
				$res = false;
			return $res;
		} else {
			return false;
		}
	}
	/**
	 * Удаление записи в таблице
	 * @param int $id
	 * @return boolean
	 */
	public function delete($id) {
		if (is_array ( $id )) {
			$this->beforeDelete ( $id );
			$res = $this->table->delete ( "`id` IN(" . implode ( ',', $id ) . ")" );
			$this->afterDelete ( $id );
			
			if ($res > 0) {
				$this->afterChange();
				$this->globalChange ();
				return true;
			} else {
				return false;
			}
		} else {
			$id = preg_replace ( '/\D/', '', $id );
			if ($id > 0) {
				$this->beforeDelete ( $id );
				$res = $this->table->delete ( "`id`='" . $id . "'" );
				$this->afterDelete ( $id );
				if ($res > 0) {
					$this->afterChange();
					$this->globalChange ();
					return true;
				} else {
					return false;
				}
			} else {
				return false;
			}
		}
	}
	/**
	 * Поиск или вставка новой строки
	 * @param string $where
	 * @param array $params
	 * @return int
	 */
	public function findOrCreate($where, $params) {
		$res = $this->table->select()->where ( $where )->query()->fetch ();
		if ($res) {
			$id = $res ['id'];
		} else {
			$id = $this->create ( $params );
		}
		return ($id);
	}
	/**
	 * Вставка новой записи или обновление существующей
	 * @param string $where
	 * @param array $params
	 * @return int
	 */
	public function createOrUpdate($where, $params) {
		$res = $this->table->select ()->where ( $where )->query ()->fetch ();
		if ($res) {
			$id = $res ['id'];
			$this->update ( $id, $params );
		} else {
			$id = $this->create ( $params );
		}
		return ($id);
	}
	/**
	 * Вставка нескольких строк сразу
	 * метод отличается от обычного метода create высокой скоростью работы
	 * @param unknown_type $params
	 * @return boolean
	 */
	public function createMultiple($params) {
		if (sizeof ( $params ) > 0) {
			$fields = array_keys ( $params [0] );
			$fields_sec = array ();
			foreach ( $fields as $key => $value ) {
				$fields_sec [$key] = '`' . $value . '`';
			}
			$tbname = $this->table->info ( 'name' );
			$select = 'INSERT INTO `' . $tbname . '` ';
			$select .= "(" . implode ( ',', $fields_sec ) . ")";
			$select .= ' VALUES ';
			foreach ( $params as $row ) {
				$select .= "(";
				foreach ( $fields as $field ) {
					$select .= "'" . addslashes ( $row [$field] ) . "',";
				}
				$select = mb_substr ( $select, 0, mb_strlen ( $select, 'UTF-8' ) - 1, 'UTF-8' );
				$select .= "),";
			}
			$select = mb_substr ( $select, 0, mb_strlen ( $select, 'UTF-8' ) - 1, 'UTF-8' );
			try {
				$res = $this->table->getAdapter ()->query ( $select );
			} catch ( Exception $e ) {
				trigger_error ( $e->getMessage (), E_USER_WARNING );
				$res = false;
			}
			return $res;
		} else
			return false;
	}
	
	//INFO
	public function getTableName() {
		$table = $this->table;
		$info = $table->info ();
		return ($info ['name']);
	}
	public function getTable() {
		return $this->table;
	}
	//EVENTS
	public function beforeCreate($params) {
		$params = $this->raiseBehavior('beforeCreate', $params);
		return $params;
	}
	public function afterCreate($id, $params) {
		$params['id'] = $id;
		$params = $this->raiseBehavior('afterCreate', $params);
		unset($params['id']);
		return $params;
	}
	
	public function afterRead($params) {
		$params = $this->raiseBehavior('afterRead', $params);
		return $params;
	}
	
	public function beforeDelete($id) {
		$this->raiseBehavior('beforeDelete', array('id'=>$id));
	}
	
	public function afterDelete($id) {
		$this->raiseBehavior('afterDelete', array('id'=>$id));
	}
	
	public function beforeUpdate($id, $params) {
		$params['id'] = $id;
		$params = $this->raiseBehavior('beforeUpdate', $params);
		unset($params['id']);
		return $params;
	}
	
	public function afterUpdate($id, $params) {
		$params['id'] = $id;
		$params = $this->raiseBehavior('afterUpdate', $params);
		unset($params['id']);
		return $params;
	}
	
	public function afterChange() {
		$this->raiseBehavior('afterChange');
	}
	
	//Для глобальных изменений
	public function globalChange() {
		//Чистка кэша
		Cache_Model_Clear::clear ( 'pages' );
		Cache_Model_Clear::clear ( 'block' );
		Cache_Model_Clear::clear ( 'search' );
	}
	
	//select
	

	public function select() {
		$select = new Zen_List_Select ();
		$select->setTable($this->getTable () );
		return $select;
	}

}